-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Have Vec use slice's implementations of Index<I> and IndexMut<I> #47832
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @kennytm (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
src/liballoc/vec.rs
Outdated
|
||
#[inline] | ||
fn index(&self, index: usize) -> &T { | ||
fn index(&self, index: I) -> &Self::Output { | ||
// NB built-in indexing via `&[T]` | ||
&(**self)[index] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not built in indexing anymore, so the comment can be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me.
Looks like this changes an error message that is breaking a UI test. + error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not satisfied
- error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::ops::Index<i32>` is not satisfied
--> $DIR/index-help.rs:13:5
|
13 | x[0i32]; //~ ERROR E0277
+ | ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
- | ^^^^^^^ vector indices are of type `usize` or ranges of `usize`
|
+ = help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32`
+ = note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[{integer}]`
- = help: the trait `std::ops::Index<i32>` is not implemented for `std::vec::Vec<{integer}>` |
@fintelia You need to update the wordings in rust/src/test/compile-fail/integral-indexing.rs Lines 16 to 19 in 560a2f4
|
@bors try - we may need crater. While the change looks reasonable, I'm afraid this will break downstream crates due to conflicting implementation. In particular, the following compiles today: use std::ops::Index;
struct S;
struct X;
struct A;
struct B;
impl Index<S> for [X] {
type Output = A;
fn index(&self, _: S) -> &A {
&A
}
}
impl Index<S> for Vec<X> {
type Output = B;
fn index(&self, _: S) -> &B {
&B
}
} I'm nominating this to @rust-lang/libs to decide whether to merge this or not. |
Have Vec use slice's implementations of Index<I> and IndexMut<I> This PR simplifies the implementation of Index and IndexMut on Vec, and in the process enables indexing Vec by any user types that implement SliceIndex. The stability annotations probably need to be changed, but I wasn't sure of the right way to do that. It also wasn't completely clear to me if this change could break any existing code.
☀️ Test successful - status-travis |
Crater run started. |
Crater results: http://cargobomb-reports.s3.amazonaws.com/pr-47382/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file. There's at least one legit failure (in "kirillkh.xword_constructor...."). |
Looks like the rest are spurious. The offending lines for the real regression: impl Index<PlacementId> for [ScoredMove] {
type Output = ScoredMove;
#[inline]
fn index(&self, index: PlacementId) -> &Self::Output {
self.index(index.0 as usize)
}
}
impl Index<PlacementId> for Vec<ScoredMove> {
type Output = ScoredMove;
#[inline]
fn index(&self, index: PlacementId) -> &Self::Output {
self.index(index.0 as usize)
}
} The good news is that, the output type of the two impls are the same, so this can be fixed by simply |
The code there also relies on specialization, so we have more wiggle room to break things since that's unstable. |
@kennytm what are the next steps on this? |
I've tagged this as waiting-on-crater |
er wait sorry, I mixed this up with something else, we decided in @rust-lang/libs triage today to merge this! @fintelia want to rebase and I'll r+? |
src/liballoc/vec.rs
Outdated
@@ -1542,146 +1542,26 @@ impl<T: Hash> Hash for Vec<T> { | |||
|
|||
#[stable(feature = "rust1", since = "1.0.0")] | |||
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] | |||
impl<T> Index<usize> for Vec<T> { | |||
type Output = T; | |||
impl<T, I> Index<I> for Vec<T> where [T]: Index<I> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we change these bounds to be the same as those for [T]
rather than delegating to T's impl explicitly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you saying you'd prefer something like this?
impl<T, I> IndexMut<I> for Vec<T>
where
I: ::core::slice::SliceIndex<[T]>,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(&mut **self, index)
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fintelia indeed!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? The one currently in the PR means that if a crate implements Index<TheirType> for [T]
they automatically get the impl for Vec<T>
too, which seems convenient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a weird layer of double-indirection that isn't used very commonly in trait bounds. It is apparently different enough that specialization treats it differently as that one regression indicates.
@bors r+ Seems like all concerns are addressed. Thanks for your patience 😃 |
📌 Commit 370df40 has been approved by |
Have Vec use slice's implementations of Index<I> and IndexMut<I> This PR simplifies the implementation of Index and IndexMut on Vec, and in the process enables indexing Vec by any user types that implement SliceIndex. The stability annotations probably need to be changed, but I wasn't sure of the right way to do that. It also wasn't completely clear to me if this change could break any existing code.
☀️ Test successful - status-appveyor, status-travis |
Have `String` use `SliceIndex` impls from `str` This PR simplifies the implementation of `Index` and `IndexMut` on `String`, and in the process enables indexing `String` by any user types that implement `SliceIndex<str>`. Similar to rust-lang#47832 r? libs Not sure if this warrants a crater run.
Have `String` use `SliceIndex` impls from `str` This PR simplifies the implementation of `Index` and `IndexMut` on `String`, and in the process enables indexing `String` by any user types that implement `SliceIndex<str>`. Similar to rust-lang#47832 r? libs Not sure if this warrants a crater run.
Rollup merge of rust-lang#120291 - pitaj:string-sliceindex, r=Amanieu Have `String` use `SliceIndex` impls from `str` This PR simplifies the implementation of `Index` and `IndexMut` on `String`, and in the process enables indexing `String` by any user types that implement `SliceIndex<str>`. Similar to rust-lang#47832 r? libs Not sure if this warrants a crater run.
This PR simplifies the implementation of Index and IndexMut on Vec, and in the process enables indexing Vec by any user types that implement SliceIndex.
The stability annotations probably need to be changed, but I wasn't sure of the right way to do that. It also wasn't completely clear to me if this change could break any existing code.